﻿#include "EditorMaterialPageView.h"

#include "Pages/Material/EditorMaterialPageViewModel.h"

#include "MaterialGraph/MaterialGraphView.h"
#include "MaterialGraph/MaterialGraphViewModel.h"

#include "Framework/Editor.h"
#include "Theme/EditorTheme.h"

#include "Widgets/Widget.h"
#include "Widgets/EditorImageButton.h"
#include "Widgets/Mouse/MouseWidget.h"
#include "Widgets/Positioners/HorizontalPositionerWidget.h"
#include "Widgets/Keyboard/KeyboardWidget.h"

#include "Window/EditorContextMenuModel.h"
#include "Window/EditorWindowGroupViewModel.h"


void REditorMaterialPageView::BindViewModel(TSharedObjectPtr<REditorPageViewModel> InViewModel)
{
    Super::BindViewModel(InViewModel);
    MaterialViewModel=InViewModel;

    {
        CClass* MaterialGraphViewClass=REditor::Get()->GetViewClass(
            MaterialViewModel->GetGraph()->GetClass()
        );
        MaterialGraphView=NewObject<RMaterialGraphView>(MaterialGraphViewClass,this);
        MaterialGraphView->BindViewModel(MaterialViewModel->GetGraph()); 
    }    
}

void REditorMaterialPageView::CreateWidget(TSharedObjectPtr<RWidget> InParent)
{
    auto Root=NewWidget<RWidget>(InParent);
    Root->Anchor.Fill(InParent);
    RWidgetWeakPtr WeakRoot=Root;

    MaterialGraphView->CreateWidget(Root);

    auto ContextMenuMouse = NewWidget<RMouseWidget>(Root);
    ContextMenuMouse->Anchor.Fill(Root);
    //这个鼠标控件仅仅是为了显示右键菜单，所以需要将鼠标事件传递给被覆盖的控件
    ContextMenuMouse->bPreventCovoredWidgetResponse=false; 
    ContextMenuMouse->OnClicked.BindLambda([this](const SMouseButtonEvent& InMouseEvent)
    {
        if(InMouseEvent.GetButton()==EMouseButton::Right )
        {
            //context menu
            TVector<SEditorContextMenuLine> RootContextMenu;

            //add add menu
            {
                auto& Add= RootContextMenu.Emplace();
                Add.Text=U"添加节点";
                Add.SubMenuWidth=150;
                
                //second level 
                {
                    auto& InputNodes=Add.SubMenus.Emplace();
                    InputNodes.Text=U"输入节点";
                
                    //third level
                    {
                        auto& Number=InputNodes.SubMenus.Emplace();
                        Number.Text=U"数字";
                        Number.OnClicked.Bind([this](){
                            this->MaterialGraphView->AddFloatNodeAtMouse();
                        });
                    }

                    {
                        auto& Vector=InputNodes.SubMenus.Emplace();
                        Vector.Text=U"向量";
                        Vector.OnClicked.Bind([this](){
                            this->MaterialGraphView->AddVectorNodeAtMouse();
                        });
                    }

                    {
                        auto& Property=InputNodes.SubMenus.Emplace();
                        Property.Text=U"顶点属性";
                        Property.OnClicked.Bind([this](){
                            this->MaterialGraphView->AddPropertyNodeAtMouse();
                        });
                    }

                    {
                        auto& Texture=InputNodes.SubMenus.Emplace();
                        Texture.Text=U"图片/纹理";
                        Texture.OnClicked.Bind([this](){
                            this->MaterialGraphView->AddTextureNodeAtMouse();
                        });

                    }

                    {
                        auto& CameraProperty=InputNodes.SubMenus.Emplace();
                        CameraProperty.Text=U"相机属性";
                        CameraProperty.OnClicked.Bind([this](){
                            this->MaterialGraphView->AddCameraNodeAtMouse();
                        });
                    }
                }

                {
                    auto& ThransformNodes=Add.SubMenus.Emplace();
                    ThransformNodes.Text=U"变换节点";

                    //third level
                    {
                        auto& Calculation=ThransformNodes.SubMenus.Emplace();
                        Calculation.Text=U"运算";
                        Calculation.OnClicked.Bind([this](){
                            this->MaterialGraphView->AddOperationNodeAtMouse();
                        });
                    }

                    {
                        auto& VectorOperation=ThransformNodes.SubMenus.Emplace();
                        VectorOperation.Text=U"向量运算";
                        VectorOperation.OnClicked.Bind([this](){
                            this->MaterialGraphView->AddVectorOperationNodeAtMouse();
                        });
                    }

                    {
                        auto& Split=ThransformNodes.SubMenus.Emplace();
                        Split.Text=U"分解向量";
                        Split.OnClicked.Bind([this](){
                            this->MaterialGraphView->AddSplitVectorNodeAtMouse();
                        });
                    }

                }
            
                //输出
                {
                    auto& OutputNodes=Add.SubMenus.Emplace();
                    OutputNodes.Text=U"输出节点";

                    //延迟BRDF
                    {
                        auto& DelayBRDF=OutputNodes.SubMenus.Emplace();
                        DelayBRDF.Text=U"延迟BRDF";
                        DelayBRDF.OnClicked.Bind([this]()
                        {
                            this->MaterialGraphView->AddDelayBRDFNodeAtMouse();
                        });
                    }

                    //无光照
                    {
                        auto& Unlit=OutputNodes.SubMenus.Emplace();
                        Unlit.Text=U"无光照";
                        Unlit.OnClicked.Bind([this]()
                        {
                            this->MaterialGraphView->AddUnlitNodeAtMouse();
                        });
                    }
                }
            
            }

            //add refresh button
            {
                auto& Refresh= RootContextMenu.Emplace();
                Refresh.Icon=MaterialViewModel->GetUpdateIcon();
                Refresh.Text=U"刷新材质";
                Refresh.OnClicked.Bind([this](){
                    MaterialViewModel->UpdateMaterial();
                });
            }

            //show context menu
            REditorWindowGroupViewModel::Get()->ShowContextMenu(
                RootContextMenu
                ,SMouseButtonEvent::GetMosuePositionOnScreen()
                ,200
            );
        }
        else 
        {
            if(InMouseEvent.GetButton()==EMouseButton::Left)
            {
                //clear selection
                MaterialGraphView->ClearNodeSelection();
            }

            if(REditorWindowGroupViewModel::Get()->IsContextMenuVisible())
            {
                REditorWindowGroupViewModel::Get()->HideContextMenu();
            }
        }

        return false;
    });

    auto Keyboard=NewWidget<RKeyboardWidget>(Root);
    Keyboard->Anchor.Fill(Root);
    Keyboard->OnKeyboardInput.Bind([this](const SKeyboardEvent& InKeyEvent)->bool
    {
        if(InKeyEvent.Key==EKey::Delete)
        {
            MaterialGraphView->DeleteSelectedNode();
            return true;
        }
        return false;
    });
    ContextMenuMouse->AutoFocusTarget=Keyboard;
    

}

void REditorMaterialPageView::FillOperations(TSharedObjectPtr<RWidget> InOperationParent)
{
    auto OperationParent=NewWidget<RHorizontalPositionerWidget>(InOperationParent);
    OperationParent->Anchor.VerticalFill(InOperationParent);
    OperationParent->Spacing= REditor::Get()->CurrentTheme->PageAreaButtonInterval;

    auto RefreshButton = WHE::CreateImageButton(
        MaterialViewModel->GetUpdateIcon()
        ,CString(U"刷新材质")
        ,[this](){
            MaterialViewModel->UpdateMaterial();
        }
        ,OperationParent
        ,REditor::Get()->CurrentTheme->PageAreaButtonSize
        ,REditor::Get()->CurrentTheme->PageAreaButtonIconSize
    );
}
